using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace WB.Mvc.Forms
{
	[Serializable]
	public class ModelFieldGroup : FieldGroup
	{
		private readonly IDictionary<PropertyDescriptor, Field> propertiesToFields;

		public ModelFieldGroup()
		{
			propertiesToFields = new Dictionary<PropertyDescriptor, Field>();
		}

		/// <summary>
		/// Add a field to the group and map it to a <see cref="PropertyDescriptor"/>
		/// so that it can be used to update models.
		/// </summary>
		public void AddField(Field field, PropertyDescriptor descriptor)
		{
			Fields.Add(field);
			propertiesToFields.Add(descriptor, field);
		}

		/// <summary>
		/// Updates with 
		/// values from <see cref="ModelFieldGroup.Fields"/>.
		/// </summary>
		public void UpdateModel(object model)
		{
			foreach (var kvp in propertiesToFields)
			{
				PropertyDescriptor property = kvp.Key;
				Field field = kvp.Value;

				try
				{
					if (property.PropertyType.IsEnum)
					{
						var value = Convert.ChangeType(field.Value, Enum.GetUnderlyingType(property.PropertyType));
						property.SetValue(model, value);
					}
					else
					{
						var value = Convert.ChangeType(field.Value, property.PropertyType);
						property.SetValue(model, value);
					}
				}
				catch (Exception ex)
				{
					throw new InvalidOperationException(string.Format("Error converting {0} to {1}.", field.Value, property.PropertyType), ex);
				}
			}
		}
	}
}